home *** CD-ROM | disk | FTP | other *** search
/ The Business Master (3rd Edition) / The Business Master (3rd Edition).iso / files / commadio / freespch / spaceinv.lzh / SPACEINV.PAS < prev   
Pascal/Delphi Source File  |  1989-07-16  |  16KB  |  578 lines

  1. PROGRAM SpaceInv;
  2.  
  3. USES CRT, DOS;
  4.  
  5. {
  6.                       VERSION 5.2 -- By Timothy Campbell
  7.                       ══════════════════════════════════
  8.                       It ain't  much,  but it does work!
  9. }
  10.  
  11.  
  12. TYPE
  13.   Line       = STRING[80];
  14.   Sprite     = STRING[7];
  15.   SpriteType = (Base,Missle,Ufo1,Bomb1,Ufo2,Bomb2,Ufo3,Bomb3,Ufo4,Bomb4,
  16.                 Ufo5,Bomb5,Ufo6,Bomb6);
  17.   Switch     = (Off,On);
  18.  
  19.  
  20. CONST
  21.   Blanks    = '       ';
  22.   DelayAdj  = 3;
  23.   DelayInit = 70;
  24.   NumSyms   = 13;
  25.   Shields   = ' '#176#177#178#219;
  26.   Sprites   : ARRAY [0..NumSyms] OF Sprite =
  27.             ( #213#209#202#209#184,
  28.               #024,
  29.               #017#016#174#153#175#017#016,
  30.               #079,
  31.               #060#243#234#242#062,
  32.               #147,
  33.               #174#017#016#175,
  34.               #015,
  35.               #017#001#016,
  36.               #157,
  37.               #199#002#182,
  38.               #031,
  39.               #233,
  40.               'v'                      );
  41.   Explode   : ARRAY [0..5] OF Sprite =
  42.             ( #219#219#219#219#219#219#219,
  43.               #178#178#178#178#178#178#178,
  44.               #177#177#177#177#177#177#177,
  45.               #176#176#176#176#176#176#176,
  46.               '- - - - -',
  47.               '       '               );
  48.  
  49. VAR
  50.   Active    : ARRAY[0..NumSyms] OF BOOLEAN;
  51.   ActiveCnt : BYTE;
  52.   Beat      : INTEGER;
  53.   BombType  : SpriteType;
  54.   DelayTime : INTEGER;
  55.   Explosion : BYTE;
  56.   InChar    : CHAR;
  57.   MisX      : BYTE;
  58.   MisY      : BYTE;
  59.   Move      : ARRAY[0..NumSyms] OF INTEGER;
  60.   MoveUfo6  : BYTE;
  61.   Noise     : BOOLEAN;
  62.   NowX      : BYTE;
  63.   NowY      : BYTE;
  64.   ShieldLev : BYTE;
  65.   RandomMod : BYTE;
  66.   Score     : INTEGER;
  67.   ShieldCnt : INTEGER;
  68.   SpriteLen : BYTE;
  69.   SprX      : BYTE;
  70.   SprY      : BYTE;
  71.   Thingy    : INTEGER;
  72.   Tick      : BYTE;
  73.   UfoTick   : BYTE;
  74.   UfoType   : SpriteType;
  75.   WX,WY     : BYTE;
  76.   XPosn     : ARRAY[0..NumSyms] OF BYTE;
  77.   YPosn     : ARRAY[0..NumSyms] OF BYTE;
  78.  
  79. FUNCTION Divis(Dv1,Dv2 : INTEGER) : BOOLEAN;
  80. BEGIN
  81.   IF (Dv1 DIV Dv2) * Dv2 = Dv1
  82.   THEN Divis := TRUE
  83.   ELSE Divis := FALSE;
  84. END;
  85.  
  86. PROCEDURE Ce(CIn : Line);
  87. BEGIN
  88.   GOTOXY(((80 - LENGTH(Cin)) DIV 2),WHEREY);
  89.   WRITELN(CIn);
  90. END;
  91.  
  92. FUNCTION Sz(SIn : Line) : Line;
  93. BEGIN
  94.   Sz := Copy((SIn + Blanks),1,7);
  95. END;
  96.  
  97. PROCEDURE DawdleJet;
  98. VAR
  99.   BanLoop : BYTE;
  100.   Mult    : INTEGER;
  101. BEGIN
  102.   Mult   := 1;
  103.   Thingy := 100;
  104.   REPEAT
  105.     Thingy := Thingy + Mult;
  106.     IF Thingy > 4000 THEN Mult := -1;
  107.     IF Thingy <  100 THEN Mult := 1;
  108.     FOR BanLoop := 1 TO 5 DO
  109.     BEGIN
  110.       SOUND(Thingy);
  111.       DELAY(1);
  112.       SOUND(4200-Thingy);
  113.       DELAY(1+RANDOM(8));
  114.     END;
  115.   UNTIL KEYPRESSED;
  116.   InChar := READKEY;
  117.   NOSOUND;
  118. END;
  119.  
  120. PROCEDURE DawdleNoise;
  121. BEGIN
  122.   REPEAT
  123.     SOUND(200+RANDOM(3000));
  124.     DELAY(1+RANDOM(8));
  125.     NOSOUND;
  126.     DELAY(1+RANDOM(50));
  127.   UNTIL KEYPRESSED;
  128.   InChar := READKEY;
  129.   NOSOUND;
  130. END;
  131.  
  132. PROCEDURE Banner;
  133. BEGIN
  134.   CLRSCR;
  135.   Ce('┌───────────────────────────────────────────────────────┬──────────────────┐');
  136.   Ce('│  Pinnacle  Software''s  Space  Investors  Video  Game  │     SPACEINV     │');
  137.   Ce('├───────────────────────────────────────────────────────┴──────────────────┤');
  138.   Ce('│  C O P Y R I G H T  (C)  1989   BY   P I N N A C L E    S O F T W A R E  │');
  139.   Ce('├──────────────────────────────────────────────────────────────────────────┤');
  140.   Ce('│ This program may be  freely distributed  so long as it is distributed in │');
  141.   Ce('│ its complete and unaltered form,  including this notice.                 │');
  142.   Ce('├──────────────────────────────────────────────────────────────────────────┤');
  143.   Ce('├───────────────  ╦══╗ ═╦═ ╦═╗ ╔ ╦═╗ ╔ ╔══╗ ╔══╗ ╦    ╦══╗  ───────────────┤');
  144.   Ce('├───────────────  ╠══╝  ║  ║ ║ ║ ║ ║ ║ ╠══╣ ║    ║    ╠═    ───────────────┤');
  145.   Ce('├─            ──  ╩    ═╩═ ╝ ╚═╝ ╝ ╚═╝ ╩  ╩ ╚══╝ ╩══╝ ╩══╝  ──            ─┤');
  146.   Ce('├  VOICE LINE  ─  ╔══╗ ╔══╗ ╦══╗ ╔═╦═╗ ╗   ╔ ╔═╗ ╦══╗ ╦══╗  ─  DATA  LINE  ┤');
  147.   Ce('├ 514-345-9578 ─  ╚══╗ ║  ║ ╠═     ║   ║ ║ ║ ╠═╣ ╠═╦╝ ╠═    ─ 514-345-8654 ┤');
  148.   Ce('├─            ──  ╚══╝ ╚══╝ ╩      ╩   ╚═╩═╝ ╩ ╩ ╩ ╚╝ ╩══╝  ──            ─┤');
  149.   Ce('├───────────────  Post Office Box 386, Town of Mount Royal  ───────────────┤');
  150.   Ce('├───────────────  Cartierville,  Quebec,  Canada,  H3P 3C6  ───────────────┤');
  151.   Ce('└──────────────────────────────────────────────────────────────────────────┘');
  152.   WRITELN;
  153.   Ce('PRESS A KEY TO CONTINUE');
  154.   DawdleJet;
  155.   CLRSCR;
  156.   Ce('PINNACLE SOFTWARE PRESENTS');
  157.   Ce('┌─-─=─=─=─=─=─=─=─=─=─=─=─=─=─=─=─-─┐');
  158.   Ce(')   S P A C E   I N V E S T O R S   (');
  159.   Ce('└─-─=─=─=─=─=─=─=─=─=─=─=─=─=─=─=─-─┘');
  160.   WRITELN;
  161.   Ce('Watch out for ...');
  162.   WRITELN;
  163.   Ce('THE MOTHER SHIP   ' + Sz(Sprites[ORD(Ufo1)]));
  164.   Ce('THE BATTLE POD    ' + Sz(' '+Sprites[ORD(Ufo2)]));
  165.   Ce('THE DRIFTER       ' + Sz(' '+Sprites[ORD(Ufo3)]));
  166.   Ce('THE HARASSER      ' + Sz('  '+Sprites[ORD(Ufo4)]));
  167.   Ce('THE DARE-DEVIL    ' + Sz('  '+Sprites[ORD(Ufo5)]));
  168.   Ce('THE OBSERVER      ' + Sz('   '+Sprites[ORD(Ufo6)]));
  169.   WRITELN;
  170.   Ce('    The keys are used as follows...                 ');
  171.   Ce('    F and J ..... move base left and right          ');
  172.   Ce('    E and I ..... either key will stop base movement');
  173.   Ce('    Spacebar .... fires a missle                    ');
  174.   Ce('    - (minus) ... toggles sound on and off          ');
  175.   Ce('    P ........... pauses the game                   ');
  176.   Ce('    ESC ......... exits the game (you coward!)      ');
  177.   WRITELN;
  178.   Ce('*** PRESS A KEY TO START ***');
  179.   DawdleNoise;
  180. END;
  181.  
  182. PROCEDURE ShowScore;
  183. BEGIN
  184.   GOTOXY(1,25);
  185.   WRITE('SCORE: ',Score,'   SHIELD LEVEL: ',
  186.   Copy(Shields,1,ShieldLev),'  ');
  187. END;
  188.  
  189. PROCEDURE Cursor(CCtl : Switch);
  190. TYPE
  191.   regpack =
  192.   RECORD
  193.     ax,bx,cx,dx,bp,di,si,ds,es,flags: INTEGER;
  194.   END;
  195. VAR
  196.   recpack : REGISTERS;
  197. BEGIN
  198.   WITH recpack DO
  199.   BEGIN
  200.     ax := $0100;
  201.     IF CCtl = On
  202.     THEN cx := $0CCD  { 12, 13 }
  203.     ELSE cx := $FFFF;
  204.   END;
  205.   INTR($10,recpack);
  206. END;
  207.  
  208. PROCEDURE BEEP(Tone : INTEGER);
  209. BEGIN
  210.   IF Noise THEN SOUND(Tone);
  211. END;
  212.  
  213. PROCEDURE SetPosn(IntST : SpriteType; IntX, IntY : BYTE);
  214. BEGIN
  215.   IF ((IntX = 0) AND (IntY = 0)) AND (Active[ORD(IntST)] = TRUE) THEN
  216.   BEGIN
  217.     Active[ORD(IntST)] := FALSE;
  218.     ActiveCnt     := ActiveCnt - 1;
  219.   END;
  220.   IF ((IntX > 0) AND (IntY > 0)) THEN
  221.   BEGIN
  222.     IF Active[ORD(IntST)] = FALSE THEN
  223.     BEGIN
  224.       Active[ORD(IntST)] := TRUE;
  225.       IF (RANDOM(100) < 33) AND (IntST IN [Ufo1,Ufo2,Ufo3,Ufo4,Ufo5,Ufo6]) THEN
  226.       BEGIN
  227.         Move[ORD(IntST)]   := -1;
  228.         IntX := 80 - LENGTH(Sprites[ORD(IntST)]) - 1;
  229.       END
  230.       ELSE Move[ORD(IntST)]   := 1;
  231.       ActiveCnt          := ActiveCnt + 1;
  232.     END;
  233.     XPosn[ORD(IntST)]  := IntX;
  234.     YPosn[ORD(IntST)]  := IntY;
  235.   END;
  236. END;
  237.  
  238. PROCEDURE FindXY(FndST : SpriteType);
  239. BEGIN
  240.   NowX := XPosn[ORD(FndST)];
  241.   NowY := YPosn[ORD(FndST)];
  242. END;
  243.  
  244. {======= MOVEMENT =======}
  245.  
  246. PROCEDURE MoveX(SprTyp : SpriteType);
  247. VAR
  248.   OutSprite : STRING[9];
  249.   XGo       : BYTE;
  250.   YGo       : BYTE;
  251. BEGIN
  252.   OutSprite := Sprites[ORD(SprTyp)];
  253.   SpriteLen := Length(OutSprite);
  254.   FindXY(SprTyp);
  255.   IF SprTyp <> Base THEN
  256.   BEGIN
  257.     IF (RANDOM(1000) < SpriteLen * 5)
  258.     OR ((SprTyp = Ufo6) AND (RANDOM(100) < 5)) THEN
  259.     BEGIN
  260.       IF NowX < XPosn[ORD(Base)] THEN Move[ORD(SprTyp)] := 1;
  261.       IF NowX > XPosn[ORD(Base)] THEN Move[ORD(SprTyp)] := -1;
  262.     END;
  263.   END;
  264.   XGo := NowX + Move[ORD(SprTyp)];
  265.   IF XGo < 1 THEN XGo := 1;
  266.   IF XGo + SpriteLen > 80 THEN XGo := 80 - SpriteLen;
  267.   SetPosn(SprTyp,XGo,NowY);
  268.   IF SprTyp <> Base THEN
  269.   BEGIN
  270.     IF RANDOM(120) < ORD(SprTyp) THEN
  271.     BEGIN
  272.       OutSprite := COPY(Blanks,1,SpriteLen);
  273.       IF RANDOM(100) < 33
  274.       THEN YGo := NowY - 1
  275.       ELSE YGo := NowY + 1;
  276.       IF YGo < 1  THEN YGo := 1;
  277.       IF YGo > 18 THEN YGo := 17;
  278.       GOTOXY(NowX,YGo);
  279.       WRITE(Sprites[ORD(SprTyp)]);
  280.       FOR Thingy := 40 DOWNTO 5 DO BEEP(Thingy * 100);
  281.       SetPosn(SprTyp,NowX,YGo);
  282.     END;
  283.   END;
  284.   IF (XGo > 1) AND (Move[ORD(SprTyp)] > 0) THEN
  285.   BEGIN
  286.     XGo := XGo - 1;
  287.     OutSprite := ' ' + OutSprite;
  288.   END;
  289.   IF (XGo < 80) AND (Move[ORD(SprTyp)] < 0) THEN OutSprite := OutSprite + ' ';
  290.   GOTOXY(XGo,NowY);
  291.   WRITE(OutSprite);
  292. END;
  293.  
  294. PROCEDURE CheckBoom(BWep, Wnme : SpriteType; MisX, MisY : BYTE);
  295.   BEGIN
  296.     FindXY(Wnme);
  297.     SpriteLen := LENGTH(Sprites[ORD(Wnme)]);
  298.     IF (MisX IN [NowX .. (NowX + SpriteLen-1)]) AND (MisY = NowY)
  299.     AND Active[ORD(Wnme)]
  300.     THEN
  301.     BEGIN
  302.       FOR Explosion := 0 TO 5 DO
  303.       BEGIN
  304.         FOR Thingy := 1 TO (SpriteLen * 10) DO
  305.         BEGIN
  306.           DELAY(1);
  307.           BEEP(500+RANDOM(4000 - Thingy * 50));
  308.         END;
  309.         GOTOXY(NowX,NowY);
  310.         WRITE(Copy(Explode[Explosion],1,SpriteLen));
  311.       END;
  312.       IF BWep = Missle THEN
  313.       BEGIN
  314.         Score := Score + (14 - ORD(Wnme)) * 10;
  315.         SetPosn(Wnme,0,0);
  316.         SetPosn(Missle,0,0);
  317.       END
  318.       ELSE
  319.       BEGIN
  320.         IF Divis(Beat,3)
  321.         THEN Move[ORD(PRED(BWep))] := Move[ORD(PRED(Bwep))] * -1;
  322.         Score := Score - 100;
  323.         IF Score < 0 THEN Score := 0;
  324.         SetPosn(BWep,0,0);
  325.         ShieldLev   := ShieldLev - 1;
  326.       END;
  327.       ShowScore;
  328.     END;   { Weapon hit enemy }
  329.   END;     { CheckBoom }
  330.  
  331.  
  332. PROCEDURE MoveWeapon(WType : SpriteType);
  333.   BEGIN
  334.     IF Active[ORD(WType)] THEN
  335.     BEGIN
  336.       FindXY(WType);
  337.       GOTOXY(NowX,NowY);
  338.       WRITE(' ');
  339.       IF (PRED(WType) IN [Ufo1,Ufo2]) THEN
  340.       BEGIN
  341.         {-- Smart Bomb --}
  342.         IF Divis(Beat,ORD(WType)*3)
  343.         AND Active[ORD(PRED(WType))]
  344.         THEN
  345.         BEGIN
  346.           FOR Thingy := 1 TO (Score DIV 1000) DO
  347.           BEGIN
  348.             IF XPosn[ORD(Base)] > NowX THEN NowX := NowX + 1;
  349.             IF XPosn[ORD(Base)] < NowX THEN NowX := NowX - 1;
  350.           END;
  351.         END;
  352.       END;
  353.       IF WType = Missle
  354.       THEN NowY := NowY - 1
  355.       ELSE NowY := NowY + 1;
  356.       IF NOT (NowY IN [1..24])
  357.       THEN SetPosn(WType,0,0)
  358.       ELSE
  359.       BEGIN
  360.         BEEP(500+(ORD(WType)*RANDOM(200))+(25-NowY)*100);
  361.         GOTOXY(NowX,NowY);
  362.         WRITE(Sprites[ORD(WType)]);
  363.         SetPosn(WType,NowX,NowY);
  364.         WX := NowX;
  365.         WY := NowY;
  366.         IF WType = Missle
  367.         THEN
  368.         BEGIN
  369.           CheckBoom(WType,Ufo1,WX,WY);
  370.           CheckBoom(WType,Ufo2,WX,WY);
  371.           CheckBoom(WType,Ufo3,WX,WY);
  372.           CheckBoom(WType,Ufo4,WX,WY);
  373.           CheckBoom(WType,Ufo5,WX,WY);
  374.           CheckBoom(WType,Ufo6,WX,WY);
  375.         END
  376.         ELSE CheckBoom(WType,Base,WX,WY);
  377.       END;     { Weapon on screen }
  378.     END;       { Specified weapon active }
  379.   END;
  380.  
  381.  
  382. PROCEDURE MoveUfo(UfoST : SpriteType);
  383.   BEGIN
  384.     {--- Ufo Movement ---}
  385.     IF Active[ORD(UfoST)] THEN
  386.     BEGIN
  387.       IF (Tick IN [1..7]) THEN Move[ORD(UfoST)] := Move[ORD(UfoST)] * -1;
  388.       UfoTick := UfoTick + RANDOM(3);
  389.       IF UfoTick > 99 THEN UfoTick := 0;
  390.       IF Divis(UfoTick,(ORD(UfoST) DIV 2)) THEN
  391.       BEGIN
  392.         MoveX(UfoST);
  393.         BEEP(ORD(UfoST) * 300);
  394.         DELAY(1);
  395.         SprX := NowX;
  396.         FindXY(Base);
  397.         {--- Drop a bomb? ---}
  398.         IF (NOT Active[ORD(UfoST)+1])        { Not if one already dropping }
  399.         AND
  400.         (((Beat < LENGTH(Sprites[ORD(UfoST)])*10) AND
  401.         (SprX IN [NowX-1,NowX,NowX+1]))      { Bigger Ufo's use good shots }
  402.         OR
  403.         (Beat < (Score DIV 20)))             { 100% chance at score 2000 }
  404.         AND (NOT ((UfoST = Ufo6) AND (RANDOM(1000) < 995)))  { Rare bomber }
  405.         THEN
  406.         BEGIN
  407.           BEEP(1200);
  408.           FindXY(UfoST);
  409.           SetPosn(SUCC(UfoST),
  410.           (NowX+(LENGTH(Sprites[ORD(UfoST)]) DIV 2)),
  411.           NowY+1);
  412.         END;
  413.         SpriteLen := LENGTH(Sprites[ORD(UfoST)]);
  414.         FindXY(UfoST);
  415.         IF (NowX = 1) OR ((NowX + SpriteLen) > 79) THEN
  416.         BEGIN
  417.           SetPosn(UfoST,0,0);
  418.           BEEP(3500);
  419.           GOTOXY(NowX,NowY);
  420.           WRITE(Copy(Blanks,1,SpriteLen));
  421.         END;
  422.       END;   { Ufo Movement }
  423.     END;     { Ufo Introduction }
  424.   END;       { MoveUfo }
  425.  
  426. {======= INITIALIZATION =======}
  427.  
  428.  
  429. PROCEDURE StartUp;
  430.   VAR
  431.     Loop1    : BYTE;
  432.  
  433.   BEGIN
  434.     Banner;
  435.     CLRSCR;
  436.     ActiveCnt := 0;
  437.     Beat      := 0;
  438.     InChar    := '?';
  439.     Noise     := TRUE;
  440.     RandomMod := 0;
  441.     Score     := 0;
  442.     ShieldCnt := 0;
  443.     ShieldLev := 5;
  444.     UfoTick   := 0;
  445.     FOR Loop1 := 0 TO NumSyms DO
  446.     BEGIN
  447.       Active[Loop1] := FALSE;
  448.       Move[Loop1]   := 0;
  449.       XPosn[Loop1]  := 0;
  450.       YPosn[Loop1]  := 0;
  451.     END;
  452.     SetPosn(Base,39,24);
  453.   END;
  454.  
  455.  
  456. {======= MAINLINE =======}
  457.  
  458.  
  459. BEGIN
  460.   StartUp;
  461.   Cursor(Off);
  462.   ShowScore;
  463.   REPEAT
  464.     IF (Score DIV 1000 > ShieldCnt) AND (ShieldLev < 5)
  465.     THEN
  466.     BEGIN
  467.       ShieldLev := ShieldLev + 1;
  468.       ShieldCnt := ShieldCnt + 1;
  469.       ShowScore;
  470.     END;
  471.     {--- Beats and Ticks ---}
  472.     Tick := RANDOM(50) + RandomMod;
  473.     IF InChar = 'F' THEN RandomMod := RandomMod + 1;
  474.     IF RandomMod > 50 THEN RandomMod := 0;
  475.     Beat := Beat + 1;
  476.     IF Beat > 100 THEN Beat := 0;
  477.     {--- Commands ---}
  478.     IF KEYPRESSED THEN
  479.     BEGIN
  480.       BEEP(500);
  481.       InChar := READKEY;
  482.       InChar := UPCASE(InChar);
  483.       CASE InChar OF
  484.       '-' : BEGIN
  485.               Noise := NOT Noise;
  486.               NOSOUND;
  487.             END;
  488.       'F' : Move[ORD(Base)] := -1;
  489.       'J' : Move[ORD(Base)] := 1;
  490.       'I' : Move[ORD(Base)] := 0;
  491.       'E' : Move[ORD(Base)] := 0;
  492.       ' ' : BEGIN
  493.               Score := Score - 1;
  494.               IF Score < 0 THEN Score := 0;
  495.               IF Active[ORD(Missle)] THEN
  496.               BEGIN
  497.                 FindXY(Missle);
  498.                 GOTOXY(NowX,NowY);
  499.                 WRITE(' ');
  500.               END;
  501.               BEEP(2200);
  502.               FindXY(Base);
  503.               SetPosn(Missle,NowX+3,23);
  504.             END;  { SPACE CASE }
  505.       'P' : BEGIN
  506.               NOSOUND;
  507.               GOTOXY(70,1);
  508.               WRITE('*PAUSED*');
  509.               REPEAT UNTIL KEYPRESSED;
  510.               InChar := READKEY;
  511.               InChar := '?';
  512.               GOTOXY(70,1);
  513.               WRITE('        ');
  514.             END;
  515.       END;        { CASE }
  516.   END;
  517.   {--- Timing Delay ---}
  518.   DelayTime := DelayInit - ActiveCnt * DelayAdj;
  519.   DelayTime := DelayTime - (Score DIV 250);
  520.   IF DelayTime < 0 THEN DelayTime := 0;
  521.   IF Divis(Beat,10) THEN BEEP(150);
  522.   DELAY(DelayTime);
  523.   {--- Base Movement ---}
  524.   MoveX(Base);
  525.   IF (Divis(Beat,2)) AND (Move[ORD(Base)] <> 0)
  526.   THEN BEEP(1000+NowX*10)
  527.   ELSE NOSOUND;
  528.   {--- Weapon Movement ---}
  529.   MoveWeapon(Missle);
  530.   IF ShieldLev > 0 THEN
  531.   BEGIN
  532.     {--- Bring in a new UFO? ---}
  533.     UfoType := Ufo1;
  534.     IF Beat > 10 THEN UfoType := Ufo2;
  535.     IF Beat > 25 THEN UfoType := Ufo3;
  536.     IF Beat > 50 THEN UfoType := Ufo4;
  537.     IF Beat > 75 THEN UfoType := Ufo5;
  538.     IF Beat > 90 THEN UfoType := Ufo6;
  539.     IF ((RANDOM(1000) <= (Score DIV 100) + 15)
  540.     OR (ActiveCnt <= 2))
  541.     AND (Active[ORD(UfoType)] = FALSE)
  542.     THEN SetPosn(UfoType,1,ORD(UfoType) + RANDOM(5));
  543.     MoveWeapon(Bomb1);
  544.     MoveUfo(Ufo1);
  545.     MoveWeapon(Bomb2);
  546.     MoveUfo(Ufo2);
  547.     MoveWeapon(Bomb3);
  548.     MoveUfo(Ufo3);
  549.     MoveWeapon(Bomb4);
  550.     MoveUfo(Ufo4);
  551.     MoveWeapon(Bomb5);
  552.     MoveUfo(Ufo5);
  553.     MoveWeapon(Bomb6);
  554.     FOR MoveUfo6 := 1 to 5 DO
  555.     BEGIN
  556.       MoveUfo(Ufo6);
  557.     END;
  558.   END;              { ShieldLev > 0 }
  559.   IF ShieldLev <= 0 THEN
  560.   BEGIN
  561.     CLRSCR;
  562.     WRITELN;
  563.     WRITELN('             G A M E   O V E R  --  Score: ',Score);
  564.     WRITELN;
  565.     IF Noise THEN
  566.     BEGIN
  567.       FOR Thingy := 4 DOWNTO 1 DO
  568.       BEGIN
  569.         SOUND(500+Thingy * 1000);
  570.         DELAY(500+RANDOM(5-Thingy)*80);
  571.       END;
  572.     END;
  573.   END;
  574.   UNTIL (InChar = #27) OR (ShieldLev = 0);
  575.   NOSOUND;
  576.   Cursor(On);
  577. END.
  578.